package com.xdb.sqlparser.ast.expr;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.xdb.sqlparser.ast.SQLExpr;
import com.xdb.sqlparser.ast.AbstractSQLExprImpl;
import com.xdb.sqlparser.ast.SQLOrderBy;
import com.xdb.sqlparser.ast.SQLOver;
import com.xdb.sqlparser.visitor.SQLAstVisitor;
/**
 * 表示聚合字段
 * @author woate
 *
 */
public class SQLAggregateExpr extends AbstractSQLExprImpl implements Serializable {

	private static final long serialVersionUID = 1L;
	/**
	 * 聚合函数方法名
	 */
	protected String methodName;
	/**
	 * 聚合函数修饰词
	 */
	protected SQLAggregateOption option;
	/**
	 * 聚合函数参数列表
	 */
	protected final List<SQLExpr> arguments = new ArrayList<SQLExpr>();
	protected SQLOver over;
	
	protected SQLOrderBy withinGroup;
	protected boolean ignoreNulls = false;

	public SQLAggregateExpr(String methodName) {
		this.methodName = methodName;
	}

	public SQLAggregateExpr(String methodName, SQLAggregateOption option) {
		this.methodName = methodName;
		this.option = option;
	}
	/**
	 * 聚合函数方法名
	 * @return
	 */
	public String getMethodName() {
		return this.methodName;
	}
	/**
	 * 聚合函数方法名
	 * @param methodName
	 */
	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

	public SQLOrderBy getWithinGroup() {
		return withinGroup;
	}

	public void setWithinGroup(SQLOrderBy withinGroup) {
		if (withinGroup != null) {
			withinGroup.setParent(this);
		}

		this.withinGroup = withinGroup;
	}
	/**
	 * 聚合函数修饰词
	 * @return
	 */
	public SQLAggregateOption getOption() {
		return this.option;
	}
	/**
	 * 聚合函数修饰词
	 * @param option
	 */
	public void setOption(SQLAggregateOption option) {
		this.option = option;
	}
	/**
	 * 聚合函数参数列表
	 * @return
	 */
	public List<SQLExpr> getArguments() {
		return this.arguments;
	}

	public SQLOver getOver() {
		return over;
	}

	public void setOver(SQLOver over) {
		this.over = over;
	}

	public boolean isIgnoreNulls() {
		return this.ignoreNulls;
	}

	public void setIgnoreNulls(boolean ignoreNulls) {
		this.ignoreNulls = ignoreNulls;
	}

	@Override
	protected void accept0(SQLAstVisitor visitor) {
		if (visitor.visit(this)) {
			acceptChild(visitor, this.arguments);
			acceptChild(visitor, this.over);
		}

		visitor.endVisit(this);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((arguments == null) ? 0 : arguments.hashCode());
		result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());
		result = prime * result + ((option == null) ? 0 : option.hashCode());
		result = prime * result + ((over == null) ? 0 : over.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		SQLAggregateExpr other = (SQLAggregateExpr) obj;
		if (arguments == null) {
			if (other.arguments != null) {
				return false;
			}
		} else if (!arguments.equals(other.arguments)) {
			return false;
		}
		if (methodName == null) {
			if (other.methodName != null) {
				return false;
			}
		} else if (!methodName.equals(other.methodName)) {
			return false;
		}
		if (over == null) {
			if (other.over != null) {
				return false;
			}
		} else if (!over.equals(other.over)) {
			return false;
		}
		if (option != other.option) {
			return false;
		}
		return true;
	}

}
